package com.itsu.app.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.itsu.app.exception.MyException;
import com.itsu.app.interceptor.UserThreadLocal;
import com.itsu.interfaces.entity.*;
import com.itsu.interfaces.service.VideoService;
import com.itsu.pojo.constants.Constants;
import com.itsu.pojo.enums.CommentType;
import com.itsu.pojo.enums.ResultCode;
import com.itsu.pojo.results.ErrorResult;
import com.itsu.pojo.vo.PageResult;
import com.itsu.pojo.vo.VideoVo;
import org.apache.dubbo.config.annotation.Reference;
import org.bson.types.ObjectId;
import org.codehaus.jettison.Convention;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

@Service
public class AppVideoService {

    @Reference
    VideoService videoService;

    @Autowired
    AppUserInfoService appUserInfoService;

    @Autowired
    AppCommentService appCommentService;

    @Autowired
    AppPublishService appPublishService;

    @Autowired
    FastFileStorageClient storageClient;

    @Autowired
    FdfsWebServer fdfsWebServer;

    @Autowired
    IdService idService;

    @Autowired
    RedisTemplate<String, String> redisTemplate;

    /**
     * 上传video
     * @param imageFile
     * @param videoFile
     */
    public void saveVideo(MultipartFile imageFile, MultipartFile videoFile) {
        if (ObjectUtil.isEmpty(videoFile)) {
            throw new MyException(new ErrorResult(ResultCode.VIDEO_NULL));
        }

        String imageType = StrUtil.subAfter(imageFile.getOriginalFilename(), ".", true);
        if (!StrUtil.equalsAnyIgnoreCase(imageType, "jpg", "png", "gif", "jpeg")) {
            throw new MyException(new ErrorResult(ResultCode.PHOTO_FORMART_ERROR));
        }

        if ((imageFile.getSize() / 1024 / 1024) > 2) {
            throw new MyException(new ErrorResult(ResultCode.PHOTO_SIZE_ERROR));
        }

        String videoType = StrUtil.subAfter(videoFile.getOriginalFilename(), ".", true);
        if (!StrUtil.equalsAnyIgnoreCase(videoType, "mp4", "rmvb", "mkv", "avi")) {
            throw new MyException(new ErrorResult(ResultCode.VIDEO_FORMART_ERROR));
        }

        if ((imageFile.getSize() / 1024 / 1024) > 50) {
            throw new MyException(new ErrorResult(ResultCode.VIDEO_SIZE_ERROR));
        }


        Video build = null;
        try {
            build = Video.builder()
                    .vid(idService.createId("VIDEO"))
                    .userId(UserThreadLocal.getUid())
                    .videoUrl(uploadFile(imageFile.getInputStream(), imageFile.getSize(), imageType))
                    .picUrl(uploadFile(videoFile.getInputStream(), videoFile.getSize(), videoType))
                    .text("你好啊")
                    .created(System.currentTimeMillis())
                    .build();
        } catch (IOException e) {
            e.printStackTrace();
        }

        videoService.saveVideo(build);
    }

    /**
     * 获取video列表
     * @param page
     * @param pageSize
     * @return
     */
    public PageResult getVideos(Integer page, Integer pageSize) {
        String vidList = redisTemplate.opsForValue().get(Constants.VIDEOS_RECOMMEND + UserThreadLocal.getUid());
        List<Video> videos = Collections.emptyList();
        List<Video> allVideo = videoService.getVideos();

        if (StrUtil.isEmpty(vidList)) {
            videos = videoService.randomVideo(pageSize);
        } else {
            List<String> vids = CollUtil.sub(StrUtil.split(vidList, ","), (page - 1) * pageSize, NumberUtil.min(page * pageSize, StrUtil.split(vidList, ",").size()));
            Map<Long, Video> videoOfVidMap = CollUtil.fieldValueMap(allVideo, "vid");
            for (String vid : vids) {
                videos.add(videoOfVidMap.get(Convert.toLong(vid)));
            }
        }

        List<VideoVo> videoVoList = new ArrayList<>();
        for (Video video : videos) {
            UserInfoEntity entity = appUserInfoService.findUserByUid(video.getUserId());
            VideoVo videoVo = new VideoVo();
            videoVo.setId(video.getId().toHexString());
            videoVo.setUserId(video.getUserId());
            videoVo.setAvatar(entity.getLogo());
            videoVo.setNickname(entity.getNickName());
            videoVo.setCover(entity.getCoverPic());
            videoVo.setVideoUrl(video.getVideoUrl());
            videoVo.setCover(video.getPicUrl());
            videoVo.setSignature(video.getText());
            videoVo.setLikeCount(Convert.toInt(appCommentService.queryLikedCount(video.getId())));
            videoVo.setHasLiked(Convert.toInt(appCommentService.queryCommentStatus(video.getId(), UserThreadLocal.getUid(), CommentType.LIKED.getValue())));
            videoVo.setHasFocus(Convert.toInt(videoService.hasFocus(UserThreadLocal.getUid(), video.getUserId())));
            videoVo.setCommentCount(Convert.toInt(appCommentService.queryCommentCount(video.getId())));
            videoVoList.add(videoVo);
        }

        return new PageResult(page, pageSize, Convert.toLong(allVideo.size()), videoVoList);
    }

    /**
     * 发布video评论
     * @param id
     * @param text
     */
    public void publishVideoComment(String id, String text) {
        Video video = videoService.getVideoById(new ObjectId(id));
        Comment comment = new Comment();
        comment.setPublishId(new ObjectId(id));
        comment.setCommentType(CommentType.COMMENT.getValue());
        comment.setContent(text);
        comment.setUserId(UserThreadLocal.getUid());
        comment.setPublishUserId(video.getUserId());
        comment.setIsParent(null);
        comment.setParentId(null);
        comment.setCreated(System.currentTimeMillis());

        appCommentService.addComments(comment);
    }

    private String uploadFile(InputStream file, Long fileSize, String fileSuffixName) {
        StorePath storePath = storageClient.uploadFile(file, fileSize, fileSuffixName, null);
        return fdfsWebServer.getWebServerUrl() + "/" + storePath.getFullPath();
    }

    /**
     * 点赞video
     * @param id
     */
    public void likeVideo(String id) {
        Video video = videoService.getVideoById(new ObjectId(id));
        Comment comment = Comment.builder()
                .publishId(new ObjectId(id))
                .userId(UserThreadLocal.getUid())
                .publishUserId(video.getUserId())
                .commentType(CommentType.LIKED.getValue())
                .content(null)
                .isParent(false)
                .parentId(null)
                .created(System.currentTimeMillis())
                .build();
        appCommentService.addComments(comment);
    }

    /**
     * 取消视频点赞
     * @param id
     */
    public void dislikeVideo(String id) {
        Video video = videoService.getVideoById(new ObjectId(id));
        Comment comment = Comment.builder()
                .publishId(new ObjectId(id))
                .userId(UserThreadLocal.getUid())
                .publishUserId(video.getUserId())
                .commentType(CommentType.LIKED.getValue())
                .content(null)
                .isParent(false)
                .parentId(null)
                .created(System.currentTimeMillis())
                .build();
        appCommentService.deleteComments(comment);
    }

    /**
     * 点赞视频评论
     * @param commentId
     */
    public void likeVideoComments(String commentId) {
        Long aLong = appCommentService.commentsLike(new ObjectId(commentId));
        System.out.println(aLong);
    }

    /**
     * 取消视频评论点赞
     * @param commentId
     */
    public void dislikeVideoComments(String commentId) {
        Long aLong = appCommentService.commentsDislike(new ObjectId(commentId));
        System.out.println(aLong);
    }

    /**
     *
     * 关注视频用户
     * @param uid
     */
    public void userFocus(String uid) {
        FollowUser followUser = new FollowUser();
        followUser.setUserId(UserThreadLocal.getUid());
        followUser.setFollowUserId(Convert.toLong(uid));
        followUser.setCreated(System.currentTimeMillis());
        videoService.userFocus(followUser);
    }

    /**
     * 取消关注视频用户
     * @param uid
     */
    public void userUnFocus(String uid) {
        FollowUser followUser = new FollowUser();
        followUser.setUserId(UserThreadLocal.getUid());
        followUser.setFollowUserId(Convert.toLong(uid));
        followUser.setCreated(System.currentTimeMillis());
        videoService.userUnFocus(followUser);
    }
}
